# -*- coding: utf-8 -*-

'''
Created on 2018年8月23日

@author: 李德庚

Tensorflow 教程   https://www.tensorflow.org/tutorials/keras/basic_classification


'''

import tensorflow as tf
from tensorflow import keras

import numpy as np
import matplotlib.pyplot as plt

'''
This guide uses the Fashion MNIST dataset which contains 70,000 gray scale 
images in 10 categories. The images show individual articles of clothing 
at low resolution (28 by 28 pixels)
We will use 60,000 images to train the network and 10,000 images to evaluate 
how accurately the network learned to classify images. 
You can access the Fashion MNIST directly from TensorFlow, 
just import and load the data.

 Label    Description
    0    T-shirt/top    T恤
    1    Trouser        裤子
    2    Pullover       套衫
    3    Dress          连衣裙  
    4    Coat           大衣
    5    Sandal         高跟鞋
    6    Shirt          衬衫
    7    Sneaker        运动鞋
    8    Bag            包
    9    Ankle boot     靴子

Due to the wall,you need to download the datasets from 
 https://storage.googleapis.com/tensorflow/tf-keras-datasets
and put them under %USERPROFILE%\.keras\datasets\fashion-mnist
    train-images-idx3-ubyte.gz,train-labels-idx1-ubyte.gz
    t10k-images-idx3-ubyte.gz,t10k-labels-idx1-ubyte.gz
'''

fashion_minst = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_minst.load_data()

'''
Each image is mapped to a single label. Since the class names 
are not included with the dataset, store them here to use later 
when plotting the images
'''

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

'''
The data must be preprocessed before training the network. 
If you inspect the first image in the training set, you will see
that the pixel values fall in the range of 0 to 255
'''

plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.gca().grid(False)
plt.show()

'''
We scale these values to a range of 0 to 1 before feeding to 
the neural network model. For this, cast the datatype of the image 
components from an integer to a float, and divide by 255.
'''
train_images=train_images/255.0
test_images=test_images/255.0

'''
display the first 25 images from the training set 
and display the class name below each image. 
Verify that the data is in the correct format 
and we're ready to build and train the network.
'''
plt.figure(figsize=(10,10))
for i in range(36):
    plt.subplot(6,6,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i],plt.cm.binary)
    plt.xlabel(class_names[train_labels[i]])
plt.show()


'''
Setup the layers
The basic building block of a neural network is the layer. 
Layers extract representations from the data fed into them. 
And, hopefully, these representations are more meaningful 
for the problem at hand.

Most of deep learning consists of chaining together simple layers. 
Most layers, like tf.keras.layers.Dense, have parameters that are 
learned during training.
'''

model=keras.Sequential([
    keras.layers.Flatten(input_shape=(28,28)),      #transforms the format of the images 
                                                    #from a 2d-array (of 28 by 28 pixels), 
                                                    #to a 1d-array of 28 * 28 = 784 pixels. 
    keras.layers.Dense(128,activation=tf.nn.relu),  #densely-connected, or fully-connected, 
                                                    #neural layers. 128 nodes relu layer,
    keras.layers.Dense(10,activation=tf.nn.softmax) #10-nodes softmax layer
    ])

model.compile(optimizer=tf.train.AdamOptimizer(),
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=20)

test_loss, test_acc = model.evaluate(test_images, test_labels)

print('Test accuracy:', test_acc)

predictions = model.predict(test_images)

plt.figure(figsize=(10,10))
bg=1000
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(test_images[i+bg], cmap=plt.cm.binary)
    predicted_label = np.argmax(predictions[i+bg])
    true_label = test_labels[i+bg]
    if predicted_label == true_label:
        color = 'green'
    else:
        color = 'red'
    plt.xlabel("{} ({})".format(class_names[predicted_label], 
                                class_names[true_label]),
                                color=color)
plt.show()